package com.biz.primus.ms.promotion.service.promotion;

import com.biz.primus.base.enums.CommonStatus;
import com.biz.primus.base.exception.utils.AssertUtils;
import com.biz.primus.base.vo.PageVo;
import com.biz.primus.common.utils.JsonUtils;
import com.biz.primus.common.vo.SpringPageVO;
import com.biz.primus.model.promotion.enums.PromotionGiftTypeEnum;
import com.biz.primus.model.promotion.enums.PromotionPointGiftTypeEnum;
import com.biz.primus.model.promotion.enums.PromotionTargetLimitTypeEnum;
import com.biz.primus.model.promotion.exception.PromotionExceptionType;
import com.biz.primus.model.promotion.vo.PromotionCouponVo;
import com.biz.primus.model.promotion.vo.PurchaseGiftPromotionVo;
import com.biz.primus.model.promotion.vo.PurchaseGiftRuleVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.promotion.dao.po.PurchaseGiftPromotion;
import com.biz.primus.ms.promotion.dao.repository.PurchaseGiftPromotionRepository;
import com.biz.primus.ms.promotion.trans.PurchaseGiftPromotionPo2VoMapper;
import com.google.common.collect.Lists;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 买赠满赠后台管理Service接口实现
 *
 * @author david-liu
 */
@Service
public class PurchaseGiftPromotionManagementServiceImpl extends AbstractBaseService implements PurchaseGiftPromotionManagementService {

    @Autowired
    private PurchaseGiftPromotionRepository purchaseGiftPromotionRepository;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updatePurchaseGiftPromotion(PurchaseGiftPromotionVo vo) {
        AssertUtils.notNull(vo, PromotionExceptionType.ILLEGAL_PARAMETER);
        PurchaseGiftPromotion purchaseGiftPromotion;
        if (Objects.isNull(vo.getId())) {
            purchaseGiftPromotion = new PurchaseGiftPromotion();
            purchaseGiftPromotion.setId(idService.getNextId());
        } else {
            purchaseGiftPromotion = purchaseGiftPromotionRepository.findOne(vo.getId());
        }
        purchaseGiftPromotion.setName(vo.getName());
        purchaseGiftPromotion.setDescription(vo.getDescription());
        purchaseGiftPromotion.setChannels(vo.getChannels());
        purchaseGiftPromotion.setStartTime(LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").parse(vo.getStartTime())));
        purchaseGiftPromotion.setEndTime(LocalDateTime.from(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").parse(vo.getEndTime())));
        purchaseGiftPromotion.setEffectMemberLevels(Optional.ofNullable(vo.getEffectMemberLevels()).orElse(Lists.newArrayList()).stream().map(Integer::valueOf).collect(Collectors.toList()));
        purchaseGiftPromotion.setAllowCoupon(vo.getAllowCoupon());
        purchaseGiftPromotion.setScope(vo.getScope());
        purchaseGiftPromotion.setScopeIds(Arrays.stream(StringUtils.split(vo.getScopeIds(), ",")).map(id -> Long.valueOf(StringUtils.trim(id))).collect(Collectors.toList()));
        purchaseGiftPromotion.setCommonStatus(vo.getCommonStatus());
        purchaseGiftPromotion.setUserOnceGainLimit(vo.getUserOnceGainLimit());
        if (vo.getLimitType() == PromotionTargetLimitTypeEnum.DISCOUNT_BY_PRODUCT_AMOUNT) {
            purchaseGiftPromotion.setLimitType(PromotionTargetLimitTypeEnum.DISCOUNT_BY_PRODUCT_AMOUNT);
            purchaseGiftPromotion.setLimitAmount(vo.getLimitAmount());
        } else {
            purchaseGiftPromotion.setLimitType(PromotionTargetLimitTypeEnum.DISCOUNT_BY_PRODUCT_QUANTITY);
            purchaseGiftPromotion.setLimitQuantity(vo.getLimitQuantity());
        }
        PurchaseGiftRuleVo ruleVo = new PurchaseGiftRuleVo();
        if (vo.getGiftType() == PromotionGiftTypeEnum.PRODUCT) {
            ruleVo.setGiftType(PromotionGiftTypeEnum.PRODUCT);
            ruleVo.setGiftProductQuantity(vo.getGiftProductQuantity());
            ruleVo.setLimitGiftProductStock(vo.getLimitGiftProductStock());
            ruleVo.setGiftProductIds(vo.getGiftProductIds());
        } else if (vo.getGiftType() == PromotionGiftTypeEnum.MEMBER_POINT) {
            ruleVo.setGiftType(PromotionGiftTypeEnum.MEMBER_POINT);
            if (vo.getPointGiftType() == PromotionPointGiftTypeEnum.BY_TIMES) {
                ruleVo.setPointGiftType(PromotionPointGiftTypeEnum.BY_TIMES);
                ruleVo.setPointIncreaseTimes(vo.getPointIncreaseTimes());
            } else {
                ruleVo.setPointGiftType(PromotionPointGiftTypeEnum.BY_QUANTITY);
                ruleVo.setPointQuantity(vo.getPointQuantity());
            }
        } else {
            ruleVo.setCouponIds(Optional.ofNullable(vo.getCoupons()).orElse(Lists.newArrayList()).stream().collect(Collectors.toMap(PromotionCouponVo::getId, PromotionCouponVo::getQuantity)));
        }
        purchaseGiftPromotion.setGiftDetail(JsonUtils.obj2Json(ruleVo));
        purchaseGiftPromotionRepository.save(purchaseGiftPromotion);
        return true;
    }

    @Override
    public SpringPageVO<PurchaseGiftPromotionVo> getPurchaseGiftPromotions(PageVo pageVo) {
        Page<PurchaseGiftPromotion> page = purchaseGiftPromotionRepository.findAll(pageVo.toPageRequest());
        if (!page.hasContent()) {
            return new SpringPageVO<>();
        }
        List<PurchaseGiftPromotionVo> purchaseGiftPromotionVos = new PurchaseGiftPromotionPo2VoMapper().applyWithList(page.getContent());
        return new SpringPageVO.Builder<PurchaseGiftPromotionVo>().number(page.getNumber()).totalElements(page.getTotalElements()).size(page.getSize()).content(purchaseGiftPromotionVos).build();
    }

    @Override
    public PurchaseGiftPromotionVo getPurchaseGiftPromotion(Long promotionId) {
        AssertUtils.notNull(promotionId, PromotionExceptionType.ILLEGAL_PARAMETER);
        PurchaseGiftPromotion purchaseGiftPromotion = purchaseGiftPromotionRepository.findOne(promotionId);
        AssertUtils.notNull(purchaseGiftPromotion, PromotionExceptionType.ILLEGAL_STATE);
        return new PurchaseGiftPromotionPo2VoMapper().apply(purchaseGiftPromotion);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean togglePurchaseGiftPromotionStatus(Long promotionId) {
        AssertUtils.notNull(promotionId, PromotionExceptionType.ILLEGAL_PARAMETER);
        PurchaseGiftPromotion purchaseGiftPromotion = purchaseGiftPromotionRepository.findOne(promotionId);
        AssertUtils.notNull(purchaseGiftPromotion, PromotionExceptionType.ILLEGAL_STATE);
        purchaseGiftPromotion.setCommonStatus(CommonStatus.toggle(purchaseGiftPromotion.getCommonStatus()));
        purchaseGiftPromotionRepository.save(purchaseGiftPromotion);
        return true;
    }
}
